#include "initialization.h"

#include <unistd.h>
#include "folder.h"
#include <fstream>
#include <cstdio>

bool CameraRun(HikCamera &camera)
{
  if (camera.CameraInit())
  {
    camera.SetWidthAndHeight(getCamWHParam("WidthValue"),
                             getCamWHParam("HeightValue"));
    camera.SetOffsetXAndOffsetY(getCamXYParam("OffsetX"),
                                getCamXYParam("OffsetX"));
    if (camera.StartGrabbing())
    {
      logMessage("Camera initialization successful !");
      return true;
    }
    return false;
  }
  return false;
}

bool CreateFolder(const std::string &folderpath)
{
  if (!directoryExists(folderpath))
  {
    logMessage(folderpath + " Folder does not exist. Creating...");
    if (createDirectory(folderpath))
    {
      logMessage(folderpath + " Folder created successfully.");
      return true;
    }
    else
    {
      std::cerr << "Failed to create folder!" << std::endl;
      return false;
    }
  }
  return true;
}

bool fileExists(const std::string &filePath)
{
  std::ifstream file(filePath);
  return file.good();
}

bool SystemInitialization()
{

  // 创建日志文件夹
  if (!directoryExists(LogFloderPath))
  {
    if (!createDirectory(LogFloderPath))
    {
      std::cerr << "Failed to create folder!" << std::endl;
      return false;
    }
  }

  // 删除日志文件
  std::remove(LogFilePath.c_str());

  logMessage("\n");
  logMessage("==========:Version Start Work:==========");

  // 检查创建文件夹
  CreateFolder(SaveImageFloderPath);
  CreateFolder(ParamFloderPath);
  CreateFolder(JobFileFloderPath);

  // 基本的配置参数
  ConfigureRead();
  // 参数初始化
  ParameterReadUpdate();

  return true;
}

// 基本的配置参数
void ConfigureRead()
{
  Json::Value root;
  Json::Reader reader;
  Json::FastWriter writer;

  std::ifstream file(ConfigureFilePath);
  if (file.is_open())
  {
    file >> root;
    file.close();

    IP = root["IP"].asString();
    Upper_Computer_Port = root["Upper_Computer_Port"].asInt();
    Controller_Port = root["Controller_Port"].asInt();
    Communication_Port = root["Communication_Port"].asInt();

    return;
  }
  else
  {
    root["IP"] = IP;
    root["Upper_Computer_Port"] = Upper_Computer_Port;
    root["Controller_Port"] = Controller_Port;
    root["Communication_Port"] = Communication_Port;

    std::ofstream outFile(ConfigureFilePath, std::ios::out);
    outFile << root;
    outFile.close();

    return;
  }
}

// 读取参数初始化文件
void ParameterReadUpdate()
{
  Json::Value root;
  Json::Reader reader;
  Json::FastWriter writer;

  std::ifstream file(ParamFilePath);
  if (!file.is_open())
  {
    return;
  }

  file >> root;
  file.close();

  if (root.isMember("Mapping"))
  {
    Json::Value Mapping_root;
    Mapping_root = root["Mapping"];
    ParameterMappingUpdate(Mapping_root);
  }
  if (root.isMember("Camera"))
  {
    Json::Value Camera_root;
    Camera_root = root["Camera"];
    ParameterCameraUpdate(Camera_root);
  }
  if (root.isMember("Binarization"))
  {
    Json::Value Binarization_root;
    Binarization_root = root["Binarization"];
    ParameterBinarizationUpdate(Binarization_root);
  }
  if (root.isMember("Circle"))
  {
    Json::Value Circle_root;
    Circle_root = root["Circle"];
    ParameterCircleUpdate(Circle_root);
  }
  if (root.isMember("Rentangle"))
  {
    Json::Value Rentangle_root;
    Rentangle_root = root["Rentangle"];
    ParameterRentangleUpdate(Rentangle_root);
  }
}

// 读取相机参数参数
void ParameterReadCamera(Json::Value &camera_root)
{
  Json::Value root;
  Json::Reader reader;
  Json::FastWriter writer;

  std::ifstream file(ParamFilePath);
  if (file.is_open())
  {
    file >> root;
    file.close();
  }

  if (root.isMember("Camera"))
  {
    camera_root = root["Camera"];
  }
}

// 更新映射参数
void ParameterMappingUpdate(Json::Value &Mapping_root)
{
  Affine[0][0] = Mapping_root["Affine"]["0"][0].asDouble();
  Affine[0][1] = Mapping_root["Affine"]["0"][1].asDouble();
  Affine[0][2] = Mapping_root["Affine"]["0"][2].asDouble();
  Affine[1][0] = Mapping_root["Affine"]["1"][0].asDouble();
  Affine[1][1] = Mapping_root["Affine"]["1"][1].asDouble();
  Affine[1][2] = Mapping_root["Affine"]["1"][2].asDouble();
  RobotCalibrationZ = Mapping_root["RobotCalibrationZ"].asDouble();
  RobotCalibrationA = Mapping_root["RobotCalibrationA"].asDouble();
  RobotCalibrationB = Mapping_root["RobotCalibrationB"].asDouble();
  RobotCalibrationC = Mapping_root["RobotCalibrationC"].asDouble();
}

void ParameterCameraUpdate(Json::Value &camera_root)
{
  if (camera_root.isMember("WidthValue"))
  {
    updateCamWHParam("WidthValue", camera_root["WidthValue"].asInt());
  }
  if (camera_root.isMember("HeightValue"))
  {
    updateCamWHParam("HeightValue", camera_root["HeightValue"].asInt());
  }
  if (camera_root.isMember("OffsetX"))
  {
    updateCamWHParam("OffsetX", camera_root["OffsetX"].asInt());
  }
  if (camera_root.isMember("OffsetY"))
  {
    updateCamWHParam("OffsetY", camera_root["OffsetY"].asInt());
  }
}

void ParameterBinarizationUpdate(Json::Value &Binarization_root)
{
  updateBinarParam("ThresholdValue1", Binarization_root["ThresholdValue1"].asInt());
  updateBinarParam("ThresholdValue2", Binarization_root["ThresholdValue2"].asInt());
}

void ParameterCircleUpdate(Json::Value &root)
{
  updateCircleParam("MinDist", root["MinDist"].asInt());
  updateCircleParam("CannyParam", root["CannyParam"].asInt());
  updateCircleParam("HoughParam", root["HoughParam"].asInt());
  updateCircleParam("MinRadius", root["MinRadius"].asInt());
  updateCircleParam("MaxRadius", root["MaxRadius"].asInt());
}

void ParameterRentangleUpdate(Json::Value &Rentangle_root)
{
  updateRentangleParam("ThresholdValue1", Rentangle_root["ThresholdValue1"].asInt());
  updateRentangleParam("ThresholdValue2", Rentangle_root["ThresholdValue2"].asInt());
  updateRentangleParam("MinArea", Rentangle_root["MinArea"].asInt());
  updateRentangleParam("MaxArea", Rentangle_root["MaxArea"].asInt());
}
